﻿using System;
using System.Collections.Specialized;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace TestListGenerator.Tests
{
    /// <summary>
    /// Summary description for ConfigurationTests
    /// </summary>
    [TestClass]
    public class ConfigurationTests
    {
        public ConfigurationTests()
        {
            INCLUDED_CATEGORIES.AddRange(new string[] { "IncludedTestCategory1", "IncludedTestCategory2" });
            EXCLUDED_CATEGORIES.AddRange(new string[] {"ExcludedTestCategory1", "ExcludedTestCategory2", "ExcludedTestCategory3"} );
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion


        public const string DLL_PATH = @"C:\test path\path.dll";
        public StringCollection EXCLUDED_CATEGORIES = new StringCollection();
        public StringCollection INCLUDED_CATEGORIES = new StringCollection();
        public const string OUTPUT_PATH = @"C:\test path\output\path.vsmdi";
        public const string RUN_CONFIG_PATH = @"C:\test path\config\path.runconfig";

        [TestMethod]
        public void TestManualLoad()
        {
            Configuration config = new Configuration();
            config.DllPath = DLL_PATH;
            config.ExcludedCategories = EXCLUDED_CATEGORIES;
            config.IncludedCategories = INCLUDED_CATEGORIES;
            config.OutputPath = OUTPUT_PATH;
            config.RunConfigPath = RUN_CONFIG_PATH;

            // Make sure all the values got set correctly
            Assert.AreEqual(DLL_PATH, config.DllPath, "The DLLPath wasn't set correctly in the config object");
            Assert.AreEqual(EXCLUDED_CATEGORIES, config.ExcludedCategories, "The Excluded Paths object wasn't set correctly in the config object");
            Assert.AreEqual(INCLUDED_CATEGORIES, config.IncludedCategories, "The Included Paths object wasn't set correctly in the config object");
            Assert.AreEqual(OUTPUT_PATH, config.OutputPath, "The otuput path wasn't set correctly in the config object");
            Assert.AreEqual(RUN_CONFIG_PATH, config.RunConfigPath, "The run config path wasn't set correctly in the config object");
        }

        [TestMethod]
        public void TestManualLoad_Defaults()
        {
            Configuration config = new Configuration();
            // Set the included and excluded categories and DLL path
            config.DllPath = DLL_PATH;
            config.ExcludedCategories = EXCLUDED_CATEGORIES;
            config.IncludedCategories = INCLUDED_CATEGORIES;

            // Now see that the others are set to the default values still
            Assert.AreEqual(DLL_PATH, config.DllPath, "The DLLPath wasn't set correctly in the config object");
            Assert.AreEqual(EXCLUDED_CATEGORIES, config.ExcludedCategories, "The Excluded Paths object wasn't set correctly in the config object");
            Assert.AreEqual(INCLUDED_CATEGORIES, config.IncludedCategories, "The Included Paths object wasn't set correctly in the config object");
            Assert.AreEqual(Configuration.DEFAULT_OUTPUT_PATH, config.OutputPath, "The default output path was not set correctly");
            Assert.AreEqual(Configuration.DEFAULT_RUN_CONFIG_PATH, config.RunConfigPath, "The default run config path was not set correctly");
        }

        [TestMethod]
        public void TestCommandLineLoad()
        {
            // Test loading with all arguments set
            string[] args = new string[] {
                "-d",
                DLL_PATH,
                "-i",
                "IncludedTestCategory1",
                "-i",
                "IncludedTestCategory2",
                "-e",
                "ExcludedTestCategory1",
                "-e",
                "ExcludedTestCategory2",
                "-e",
                "ExcludedTestCategory3",
                "-o",
                OUTPUT_PATH,
                "-c",
                RUN_CONFIG_PATH
            };

            // Parse them
            Configuration config = Program.ParseArguments(args);

            // Check everything was set correctly
            Assert.AreEqual(DLL_PATH, config.DllPath, "The DLLPath wasn't set correctly in the config object");
            Assert.AreEqual(EXCLUDED_CATEGORIES.Count, config.ExcludedCategories.Count, "The Excluded Paths didn't have the right amount of categories");
            for (int x = 0; x < EXCLUDED_CATEGORIES.Count; x++)
            {
                Assert.AreEqual(EXCLUDED_CATEGORIES[x], config.ExcludedCategories[x], "The Excluded Paths was missing one of the categories");
            }
            Assert.AreEqual(INCLUDED_CATEGORIES.Count, config.IncludedCategories.Count, "The Included Paths didn't have the right amount of categories");
            for (int x = 0; x < INCLUDED_CATEGORIES.Count; x++)
            {
                Assert.AreEqual(INCLUDED_CATEGORIES[x], config.IncludedCategories[x], "The Included Paths was missing one of the categories");
            }
            Assert.AreEqual(OUTPUT_PATH, config.OutputPath, "The otuput path wasn't set correctly in the config object");
            Assert.AreEqual(RUN_CONFIG_PATH, config.RunConfigPath, "The run config path wasn't set correctly in the config object");
        }

        [TestMethod]
        public void TestCommandLineLoad_Defaults()
        {
            // Test loading with out deafult arguments set
            string[] args = new string[] {
                "-d",
                DLL_PATH,
                "-i",
                "IncludedTestCategory1",
                "-i",
                "IncludedTestCategory2",
                "-e",
                "ExcludedTestCategory1",
                "-e",
                "ExcludedTestCategory2",
                "-e",
                "ExcludedTestCategory3"
            };

            // Parse them
            Configuration config = Program.ParseArguments(args);

            // Check everything was set correctly
            Assert.AreEqual(DLL_PATH, config.DllPath, "The DLLPath wasn't set correctly in the config object");
            Assert.AreEqual(EXCLUDED_CATEGORIES.Count, config.ExcludedCategories.Count, "The Excluded Paths didn't have the right amount of categories");
            for (int x = 0; x < EXCLUDED_CATEGORIES.Count; x++)
            {
                Assert.AreEqual(EXCLUDED_CATEGORIES[x], config.ExcludedCategories[x], "The Excluded Paths was missing one of the categories");
            }
            Assert.AreEqual(INCLUDED_CATEGORIES.Count, config.IncludedCategories.Count, "The Included Paths didn't have the right amount of categories");
            for (int x = 0; x < INCLUDED_CATEGORIES.Count; x++)
            {
                Assert.AreEqual(INCLUDED_CATEGORIES[x], config.IncludedCategories[x], "The Included Paths was missing one of the categories");
            }
            Assert.AreEqual(Configuration.DEFAULT_OUTPUT_PATH, config.OutputPath, "The default output path was not set correctly");
            Assert.AreEqual(Configuration.DEFAULT_RUN_CONFIG_PATH, config.RunConfigPath, "The default run config path was not set correctly");
        }
    }
}
